﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Ruleweaver.Rules.CheckMethods
{
	public sealed class IsBetweenMethod : ComparisonMethod
	{
		private readonly object _minimum;
		private readonly object _maximum;
		private readonly BoundaryType? _boundaryType;

		public IsBetweenMethod(object minimum, object maximum)
		{
			_minimum = minimum;
			_maximum = maximum;
		}

		public IsBetweenMethod(object minimum, object maximum, BoundaryType boundaryType) : this(minimum, maximum)
		{
			_boundaryType = boundaryType;
		}

		protected override MethodInfo GetMethod(Type targetType, Type checkType)
		{
			return _boundaryType == null ? GetMethod(targetType, 2) : GetMethod(targetType, 3);
		}

		protected override IEnumerable<object> GetCheckArguments(Type targetType)
		{
			yield return _minimum;
			yield return _maximum;

			if(_boundaryType != null)
			{
				yield return _boundaryType.Value;
			}
		}

		private MethodInfo GetMethod(Type targetType, int parameterCount)
		{
			return typeof(Checkable)
				.GetMethods(BindingFlags.Public | BindingFlags.Static)
				.Where(method => method.Name == "IsBetween")
				.Where(method => method.GetParameters().Length == parameterCount)
				.First()
				.MakeGenericMethod(targetType);
		}
	}
}